#!/usr/bin/env python
#!-*- coding:utf-8 -*-

from google.appengine.api import memcache
from google.appengine.ext import db

from datetime import datetime, timedelta
from calendar import monthrange
import hashlib
import time
import cgi

import models

weekdays_en = ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"]
months_en = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]

# ユーザセッションの取得
def Get_UserSession(cookies):
    if not cookies.has_key("sessionid"):
        return None

    sessionid = cookies["sessionid"]
    if sessionid == "0": return None

    us = memcache.get(sessionid)
    if us is None:
        return None
    
    us = db.Query(models.UserSession).filter("sessionid = ", sessionid).get()
    if us is None:
        return None
    else:
        return us

# セッションの作成
def Create_UserSession(request, response, userid):

    #セッションIDの生成
    hashdata = hashlib.sha1()
    hashdata.update(str(request.remote_addr) + str(time.time()) + userid)
    sessionid = hashdata.hexdigest()
 
    #データストア
    storedata = models.UserSession()
    storedata.sessionid  = sessionid
    storedata.userid     = userid
    storedata.createtime = time.time()
     
    storedata.put()
 
    #Memcache
    memcache.add(sessionid, storedata)
 
    # Cookie 有効期間は２時間
    t = datetime.today()
    t = t + timedelta(seconds=7200)
    response.headers.add_header(
                          "Set-Cookie", 
                          "sessionid=%s;expires=%s, %02d-%s-%04d %02d:%02d:%02d GMT" % \
                              ( sessionid \
                              , weekdays_en[t.weekday()] \
                              , t.day \
                              , months_en[t.month - 1] \
                              , t.year \
                              , t.hour \
                              , t.minute \
                              , t.second))

# セッションの削除
def Delete_UserSession(cookies, response=None):

    if cookies.has_key("sessionid"):
        sessionid = cookies["sessionid"]
        
        storedata = db.Query(models.UserSession).filter("sessionid = ", sessionid).get()
        if storedata is not None:
            db.delete(storedata)
        else:
            #エラー処理
            pass
        
        if not memcache.delete(sessionid):
            #エラー処理
            pass
    #必要とあらばCookieも削除してあげるよ
    if response is not None:
        response.headers.add_header("Set-Cookie", "sessionid=0;expires=Fri, 01-Jan-1950 00:00:00 GMT")

# ユーザ情報取得
def Get_UserInfo(userid):
    userinfo = db.GqlQuery("SELECT * FROM UserInfo Where userid = :1", userid)
    if userinfo.count() > 0:
        return userinfo.get()
    else:
        return None

# requestに設定されている日付の取得、生成
def Get_Date(request):
    """
    requestに設定されている日付の取得、生成
    """
    
    date_str = cgi.escape(request.get('date'))
    date_str = date_str.encode('utf-8')
    if date_str == "":
        date_dt  = datetime.today()
        date_str = "%04d%02d%02d" % (date_dt.year, date_dt.month, date_dt.day)
    else:
        date_dt = datetime(int(date_str[0:4]), int(date_str[4:6]), int(date_str[6:8]))
    
    return date_dt, date_str

# 年,月の日数を返す
def Days_Of_Month(year,month):
    """
    年,月の日数を返す
    """
    return monthrange(year, month)[1]

# 締日を元に開始日、終了日をyyyymmdd文字列で戻す
def Get_FromTo(simebi, date_yyyymmdd):
    """
    締日を元に開始日、終了日をyyyymmdd文字列で戻す
    """
    if simebi == "":
        simebi = "31"
    
    date_str = date_yyyymmdd
    if date_str == "":
        today = datetime.today()
        date_str  = "%04d%02d%02d" % (today.year, today.month, today.day)
    #print date_str

    # 引数の年月日の年月に対する月末日を生成
    wk_dd = simebi
    try:
        wk_dt = datetime(int(date_str[0:4]), int(date_str[4:6]), int(wk_dd))
    except:
        # 例外になるってことは月末ってことじゃろ
        wk_dd = str(Days_Of_Month(int(date_str[0:4]), int(date_str[4:6])))

    matsu_yyyymmdd = "%04d%02d%02d" % (int(date_str[0:4]), int(date_str[4:6]), int(wk_dd))
    matsu_yyyymmdd_dt = datetime(int(matsu_yyyymmdd[0:4]), int(matsu_yyyymmdd[4:6]), int(wk_dd))
    
    start_yyyymmdd = "%04d%02d%02d"
    ended_yyyymmdd = "%04d%02d%02d"
    if matsu_yyyymmdd >= date_str:
        # 前月の基準日+1から今月の基準日
        if matsu_yyyymmdd_dt.month == 1:
            wk_dt = datetime(matsu_yyyymmdd_dt.year - 1, 12, int(simebi))
        else:
            try:
                wk_dt = datetime(matsu_yyyymmdd_dt.year, matsu_yyyymmdd_dt.month - 1, int(simebi))
            except:
                # 例外になるってことは月末ってことじゃろ
                dd_str = str(Days_Of_Month(matsu_yyyymmdd_dt.year, matsu_yyyymmdd_dt.month - 1))
                wk_dt = datetime(int(matsu_yyyymmdd[0:4]), int(matsu_yyyymmdd[4:6]) - 1, int(dd_str))

        wk_dt = wk_dt + timedelta(days=1)        
        start_yyyymmdd = start_yyyymmdd % (wk_dt.year, wk_dt.month, wk_dt.day)
        
        ended_yyyymmdd = matsu_yyyymmdd
        
    else:
        # 今月の基準日+1日から翌月の基準日
        wk_dt = datetime(int(matsu_yyyymmdd[0:4]), int(matsu_yyyymmdd[4:6]), int(simebi))
        wk_dt = wk_dt + timedelta(days=1)
        start_yyyymmdd = start_yyyymmdd % (wk_dt.year, wk_dt.month, wk_dt.day)
        
        if int(matsu_yyyymmdd[4:6]) == 12:
            wk_dt = datetime(int(matsu_yyyymmdd[0:4]) + 1, 1, int(simebi))
        else:
            wk_dt = datetime(int(matsu_yyyymmdd[0:4]), int(matsu_yyyymmdd[4:6]) + 1, int(simebi))
        ended_yyyymmdd = ended_yyyymmdd % (wk_dt.year, wk_dt.month, wk_dt.day)

    return start_yyyymmdd, ended_yyyymmdd    

# 引数の日付をfeedmonth分Feedした年月日文字列を取得
def Get_FeedMonth(date_yyyymmdd, feedmonth):
    """
    引数の日付をfeedmonth分Feedした年月日文字列を取得
    """
    date_str = date_yyyymmdd
    if date_str == "":
        today = datetime.today()
        date_str  = "%04d%02d%02d" % (today.year, today.month, today.day)

    year, month = divmod(int(date_str[4:6]) + feedmonth, 12)
    year = year + int(date_str[0:4])
    
    # 割り切れたということは月はそのまま
    if month == 0:
        month = 12
        year = year - 1
    
    day = int(date_str[6:8])
    if day > Days_Of_Month(year, month): day = Days_Of_Month(year, month)

    return "%04d%02d%02d" % (year, month, day)

